#include "Execute.h"

Execute::Execute()
{
	path = "";
	firstTimes = true;
	allObject = NULL;

	bkgdMdl = NULL;
	binaryForeground = NULL;

	multiObject =  new MultiObject(100); // maximum 100 object
}

Execute::~Execute()
{
	if(multiObject)
	{
		delete multiObject;
		multiObject = NULL;
	}
}

void Execute::Tracking()
{	
	IplImage binary;
	CvBlobs blobs;

	initBackground();

	for( int fr = 123; fr < 219; fr++)
	{
		getPath(path, fr);
		frame = imread(path);
		getBinaryImage(binary);
		getBlobs(binary, blobs);

		numObject = blobs.size();
		allObject = new Object[numObject];
		getObjects(allObject, blobs);

		if(firstTimes)
		{
			//init for Multiple object
			multiObject->init(frame, allObject, numObject);

			firstTimes = false;
		}else
		{
			/*
			//I suppose that all object in Frame are fixed
			// I will do this hypothesis later
			*/

			//predict
			multiObject->predict(allObject, numObject);

			//measure
			multiObject->measure(frame, allObject, numObject);

			//correct
			multiObject->correct(frame, numObject);

			//update
			multiObject->update(frame);

			//render the result
			multiObject->render();
		}

		delete[] allObject;

		//imshow("binaryImage", binaryImage);
		//imshow("Frame image", frame);
		if(cvWaitKey( 100) == 27)
			break;
	}
}

void Execute::getPath( string &path, int fr )
{
	char b[4];
	path = "D:\\Hieu\\visual2012\\Video\\twopeople\\00000";
	itoa(fr, b, 10);
	if(fr<10)
		path += "00" +string(b)+ ".jpg";
	else if(fr<100)
		path += "0" +string(b)+ ".jpg";
	else
		path += string(b)+ ".jpg";
}

void Execute::initBackground()
{
	IplImage* tmp_frame = cvLoadImage("D:\\Hieu\\visual2012\\Video\\twopeople\\00000100.jpg");
	initBackgroundModel(&bkgdMdl,tmp_frame, &paramMoG);

	//we skip 23 frame first for easy using
	for(int fr = 100; fr < 123; fr++)
	{
		getPath(path, fr);
		frame = imread(path);
		*tmp_frame = frame;
		binaryForeground = updateBackground(bkgdMdl,tmp_frame);
	}
}

void Execute::getBinaryImage(IplImage &binary)
{
	binaryForeground = updateBackground(bkgdMdl,&(IplImage)frame);
	binaryImage = (Mat) binaryForeground;
	binary = binaryImage;
	cvDilate(&binary, &binary, 0, 3);
	cvErode(&binary, &binary, 0, 2);
}

void Execute::getBlobs( IplImage &binary, CvBlobs &blobs )
{
	IplImage *labelImg = cvCreateImage(cvGetSize(&binary), IPL_DEPTH_LABEL, 1);
	unsigned int result = cvLabel(&binary, labelImg, blobs); //result: sum of all pixel to be label : smallest + large + biggest
	cvFilterByArea(blobs, 300, 1000000);
	//cout<<blobs.size()<<endl;
}

void Execute::getObjects( Object* allObject,const CvBlobs &blobs )
{
	int i = 0;
	for (CvBlobs::const_iterator it=blobs.begin(); it!=blobs.end(); ++it)
	{
		allObject[i] = Object(((*it).second)->minx, ((*it).second)->miny, ((*it).second)->maxx, ((*it).second)->maxy);
		i++;
	}
}

